#ifndef __INFRA_LIST_H__
#define __INFRA_LIST_H__

#include <linux/types.h>

#include "infra_comm.h"

#ifdef __cplusplus
extern "C" {
#endif

typedef void *infra_list_handle;

typedef int32_t(*pfn_infra_list_gb_cb)(void *puserdata, void *pdata);
typedef int32_t(*pfn_infra_list_nt_cb)(void *puserdata, void *pdata);
typedef void(*pfn_infra_list_travel_cb)(void *puserdata, void *pdata);
typedef bool(*pfn_infra_list_find_cb)(void *puserdata, void *pdata);

typedef struct _infra_list_stat_info {
    uint32_t    in_count;       /* list push */
    uint32_t    out_count;      /* list pop */
    uint32_t    stash_count;    /* list's _data_count */
} infra_list_stat_info_t;

infra_list_handle infra_list_create(uint32_t depth, uint32_t max_size, bool is_block, const char *token);
int32_t infra_list_destroy(infra_list_handle handle);
int32_t infra_list_cleanup(infra_list_handle handle);

int32_t infra_list_set_depth(infra_list_handle handle, int32_t depth);
int32_t infra_list_get_depth(infra_list_handle handle, int32_t *depth);

int32_t infra_list_register_giveback_callback(infra_list_handle handle, pfn_infra_list_gb_cb callback,
                                              void *puserdata);
int32_t infra_list_unregister_giveback_callback(infra_list_handle handle);

int32_t infra_list_register_notify_callback(infra_list_handle handle, pfn_infra_list_nt_cb callback,
                                            void *puserdata);
int32_t infra_list_unregister_notify_callback(infra_list_handle handle);

int32_t infra_list_push_front(infra_list_handle handle, void *pdata);
int32_t infra_list_push_back(infra_list_handle handle, void *pdata);
void *infra_list_pop_front(infra_list_handle handle, int32_t time_out);
void *infra_list_pop_back(infra_list_handle handle, int32_t time_out);

int32_t infra_list_insert_prev(infra_list_handle handle, void *pos_data, void *pdata);
int32_t infra_list_insert_next(infra_list_handle handle, void *pos_data, void *pdata);
int32_t infra_list_remove(infra_list_handle handle, void *pdata);

int32_t infra_list_travel(infra_list_handle handle, pfn_infra_list_travel_cb callback, void *puserdata);
void *infra_list_find(infra_list_handle handle, pfn_infra_list_find_cb callback, void *puserdata);
void *infra_list_front(infra_list_handle handle);
void *infra_list_back(infra_list_handle handle);

int32_t infra_list_empty(infra_list_handle handle);
int32_t infra_list_size(infra_list_handle handle);
int32_t infra_list_get_stat(infra_list_handle handle, infra_list_stat_info_t *pstat_info);


#ifdef __cplusplus
}
#endif

#endif  /* __INFRA_LIST_H__ */